package com.neborosoft.FlyingDog.android.gui.adapters.listview;

import android.content.Context;
import android.view.View;
import android.widget.AbsListView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import com.neborosoft.FlyingDog.R;
import com.neborosoft.FlyingDog.handlers.OnDownloadButtonClick;
import com.neborosoft.FlyingDog.handlers.OnWarningButtonClick;
import com.neborosoft.FlyingDog.logic.database.content.identified.ArtSize;
import com.neborosoft.FlyingDog.logic.database.content.identified.Audio;
import com.neborosoft.android.gui.adapters.listview.SelectableViewArrayAdapter;
import com.neborosoft.android.gui.adapters.listview.ViewArrayAdapter;
import com.neborosoft.lib.FlyingDogRuntimeException;
import com.nostra13.universalimageloader.core.ImageLoader;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * Created with IntelliJ IDEA.
 * User: CM
 * Date: 28.09.12
 * Time: 2:58
 * To change this template use File | Settings | File Templates.
 */

public class SongsPlayListAdapter extends SelectableViewArrayAdapter<Audio,SongsPlayListViewHolder>{
    private static OnDownloadButtonClick onDownloadButtonClick;
    private static OnWarningButtonClick onWarningButtonClick;

    private static SongsPlayListAdapter selectedSongsAdapter;
    private static OnItemSelected<Audio> onItemSelectedListener;

    private static final ArtSize ART_SIZE = ArtSize.SMALL;
    private static final ImageLoader IMAGE_LOADER = ImageLoader.getInstance();

    private int artWidth;
    private int artHeight;

    public static OnItemSelected<Audio> getOnItemSelectedListener(){
        return onItemSelectedListener;
    }

    public static void setOnItemSelectionChangedListener(OnItemSelected<Audio> listener){
        if(onItemSelectedListener != null){
            throw new RuntimeException("onItemSelectedListener can not be initialized twice");
        }

        onItemSelectedListener = listener;
    }

    public static SongsPlayListAdapter getSelectedSongsAdapter(){
        return selectedSongsAdapter;
    }

    public static interface OnSelectedAdapterChanged{
        void onChanged(SongsPlayListAdapter adapter, SongsPlayListAdapter old);
    }

    private static Set<OnSelectedAdapterChanged> onSelectedAdapterChangedListeners =
            new HashSet<OnSelectedAdapterChanged>();

    public static void addOnSelectedAdapterChangedListener(OnSelectedAdapterChanged listener){
        onSelectedAdapterChangedListeners.add(listener);
    }

    public static void removeOnSelectedAdapterChangedListener(OnSelectedAdapterChanged listener){
        onSelectedAdapterChangedListeners.remove(listener);
    }

    public static OnDownloadButtonClick getOnDownloadButtonClick() {
        return onDownloadButtonClick;
    }

    public static void setOnDownloadButtonClick(OnDownloadButtonClick onDownloadButtonClick) {
        if(SongsPlayListAdapter.onDownloadButtonClick != null){
            throw new FlyingDogRuntimeException("SongsPlayListAdapter.onDownloadButtonClick can not be instantiated twice");
        }
        SongsPlayListAdapter.onDownloadButtonClick = onDownloadButtonClick;
    }

    public static OnWarningButtonClick getOnWarningButtonClick() {
        return onWarningButtonClick;
    }

    public static void setOnWarningButtonClick(OnWarningButtonClick onWarningButtonClick) {
        if(SongsPlayListAdapter.onWarningButtonClick != null){
            throw new FlyingDogRuntimeException("SongsPlayListAdapter.onWarningButtonClick can not be instantiated twice");
        }
        SongsPlayListAdapter.onWarningButtonClick = onWarningButtonClick;
    }

    @Override
    protected int getRootLayoutId() {
        return R.layout.all_songs_list_element;
    }

    @Override
    protected SongsPlayListViewHolder createViewHolder(View view) {
        SongsPlayListViewHolder viewHolder = new SongsPlayListViewHolder();

        viewHolder.title = (TextView)view.findViewById(R.id.listElementSongName);
        viewHolder.artist = (TextView)view.findViewById(R.id.listElementArtistName);
        viewHolder.albumArt = (ImageView)view.findViewById(R.id.smallAlbumArt);

        viewHolder.warningButton = (ImageButton)view.findViewById(R.id.metaInfoWarningButton);
        viewHolder.downloadButton = (ImageButton)view.findViewById(R.id.downloadSongButton);

        return viewHolder;
    }

    @Override
    protected int getNullLayoutId() {
        return R.layout.song_null;
    }

    @Override
    protected void reuseNullView(int position, View convertView) {
        TextView textView = (TextView)convertView;
        textView.setText("Wait please...");
    }

    private void displayAudio(Audio audio, SongsPlayListViewHolder viewHolder, int position){
        String title = audio.getName();
        String artist = audio.getArtistName();
        viewHolder.artist.setText(artist);
        viewHolder.title.setText(title);

        String artUrl = audio.getArtUrl(ART_SIZE);
        IMAGE_LOADER.displayImage(artUrl,viewHolder.albumArt);
    }

    @Override
    protected void reuseView(final Audio audio, final SongsPlayListViewHolder viewHolder, int position) {
        displayAudio(audio, viewHolder, position);

        viewHolder.warningButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(onWarningButtonClick != null){
                    onWarningButtonClick.onClick(audio, SongsPlayListAdapter.this);
                }
            }
        });

        viewHolder.downloadButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(onDownloadButtonClick != null){
                    onDownloadButtonClick.onClick(audio, SongsPlayListAdapter.this);
                }
            }
        });
    }

    @Override
    protected void onFirstViewMeasured(SongsPlayListViewHolder songsPlayListViewHolder) {
        artWidth = songsPlayListViewHolder.albumArt.getWidth();
        artHeight = songsPlayListViewHolder.albumArt.getHeight();
    }

    public static Audio translateCurrentTrackPosition(int distance){
        SongsPlayListAdapter currentSelectedAdapter = getSelectedSongsAdapter();
        if(currentSelectedAdapter == null){
            return null;
        }

        int trackPos = currentSelectedAdapter.getCurrentSelectedIndex();
        int newPosition = trackPos + distance;

        int audiosCount = currentSelectedAdapter.getCount();
        if(distance >= audiosCount){
            throw new IndexOutOfBoundsException();
        }

        if(newPosition < 0){
            newPosition = audiosCount + newPosition;
        }
        else if(newPosition >= audiosCount){
            newPosition = newPosition - audiosCount;
        }
        currentSelectedAdapter.setCurrentSelectedIndex(newPosition);

        trackPos = currentSelectedAdapter.getCurrentSelectedIndex();
        return currentSelectedAdapter.getElement(trackPos);
    }

    private void clearSelectedAdapterSelection(){
        super.setCurrentSelectedIndex(-1);
    }

    private void callOnSelectionAdapterChangedListeners(SongsPlayListAdapter adapter, SongsPlayListAdapter old){
        for(OnSelectedAdapterChanged onSelectedAdapterChanged : onSelectedAdapterChangedListeners){
            onSelectedAdapterChanged.onChanged(adapter, old);
        }
    }

    @Override
    protected void setCurrentSelectedIndex(int currentSelectedIndex) {
        if(currentSelectedIndex < 0){
            throw new IllegalArgumentException();
        }

        SongsPlayListAdapter lastSelectedAdapter = getSelectedSongsAdapter();

        if(lastSelectedAdapter != this && lastSelectedAdapter != null){
            lastSelectedAdapter.clearSelectedAdapterSelection();
            callOnSelectionAdapterChangedListeners(this, lastSelectedAdapter);
        }

        selectedSongsAdapter = this;
        int lastSelectedIndex = getCurrentSelectedIndex();
        super.setCurrentSelectedIndex(currentSelectedIndex);

        if(onItemSelectedListener != null){
            boolean selectedIndexChanged = lastSelectedIndex != currentSelectedIndex;
            Audio selectedAudio = getElement(currentSelectedIndex);
            onItemSelectedListener.onItemSelected(selectedAudio, currentSelectedIndex, selectedIndexChanged);
        }
    }

    @Override
    public void onAdapterChanged() {
        if(this != SongsPlayListAdapter.getSelectedSongsAdapter()){
            super.onAdapterChanged();
        }
    }

    public static int getSelectedIndex(){
        if(selectedSongsAdapter != null){
            return selectedSongsAdapter.getCurrentSelectedIndex();
        } else {
            return -1;
        }
    }

    public static boolean isSongSelected(){
        return getSelectedIndex() >= 0;
    }

    public static Audio selectNextTrack(){
        return translateCurrentTrackPosition(1);
    }

    public static Audio selectPrevTrack(){
        return translateCurrentTrackPosition(-1);
    }

    public static boolean contentEquals(ViewArrayAdapter a, ViewArrayAdapter b){
        if(a == b){
            return true;
        }

        if(a == null || b == null){
            return false;
        }

        if(!(a instanceof SongsPlayListAdapter) || !(b instanceof SongsPlayListAdapter)){
            return false;
        }

        List aElements = a.getElements();
        List bElements = b.getElements();

        if(aElements == null || bElements == null){
            return false;
        }

        return aElements.equals(bElements);
    }

    public boolean hasSameContentAs(ViewArrayAdapter adapter){
        return contentEquals(this, adapter);
    }

    public boolean hasSpecifiedContent(List elements){
        List<Audio> thisElements = getElements();
        if(thisElements == null || elements == null){
            return false;
        }

        return thisElements.equals(elements);
    }

    public static boolean selectedSongsAdapterHasSpecifiedContent(List elements){
        if(selectedSongsAdapter == null){
            return false;
        }

        return selectedSongsAdapter.hasSpecifiedContent(elements);
    }

    public SongsPlayListAdapter(Context context, AbsListView parent) {
        super(context, parent);
    }
}
